package org.androidpn.server.entity;

import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.androidpn.server.util.XMLUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

/**
 * entity 游戏房间
 * 
 * @author 蔡琪
 * 
 */
@Entity
@Table(name = "tk_room")
public class Room extends BaseEntity {

	private static final long serialVersionUID = 2740831233258492664L;

	public enum RoomStatus {
		/** 等待中 */
		waitting,
		/** 游戏中 */
		inGame
	}

	/** 房间名 */
	@Column(name = "name", length = 255)
	private String name;

	/** 房间状态 */
	@Column(name = "status")
	private RoomStatus status;

	/** 房主 */
	@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.REFRESH)
	private Role host;

	/** 游戏操作信息 */
	@OneToMany(mappedBy = "room", cascade = CascadeType.REMOVE, fetch = FetchType.EAGER)
	private Set<GameOperationInfo> gameOperationInfos = new TreeSet<GameOperationInfo>(
			new Comparator<GameOperationInfo>() {
				public int compare(GameOperationInfo lhs, GameOperationInfo rhs) {
					return (int) (rhs.getCreateDate().getTime() - lhs
							.getCreateDate().getTime());
				}
			});

	/** 房间中的角色 */
	@OrderBy(value = "desc")
	@OneToMany(mappedBy = "room", cascade = CascadeType.REFRESH, fetch = FetchType.EAGER)
	private Set<Role> roles = new TreeSet<Role>(new Comparator<Role>() {
		public int compare(Role lhs, Role rhs) {
			return (int) (rhs.getCreateDate().getTime() - lhs.getCreateDate()
					.getTime());
		}
	});

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public RoomStatus getStatus() {
		return status;
	}

	public void setStatus(RoomStatus status) {
		this.status = status;
	}

	public Role getHost() {
		return host;
	}

	public void setHost(Role host) {
		this.host = host;
	}

	public Set<GameOperationInfo> getGameOperationInfos() {
		return gameOperationInfos;
	}

	public void setGameOperationInfos(Set<GameOperationInfo> gameOperationInfos) {
		this.gameOperationInfos = gameOperationInfos;
	}

	public Set<Role> getRoles() {
		return roles;
	}

	public void setRoles(Set<Role> roles) {
		this.roles = roles;
	}

	/**
	 * 从xml字符串中解析出Room
	 * 
	 * @param xml
	 *            xml字符串
	 * @return Room对象
	 */
	@Transient
	public static Room fromXML(String xml) {
		Room room = BaseEntity.fromXML(xml, Room.class);
		Document doc;
		try {
			doc = DocumentHelper.parseText(xml);
			Element element = doc.getRootElement();
			// 组装Room信息
			String name = element.elementText("name");
			String status = element.elementText("status");
			/** 房主信息 */
			Role host = null;
			Element roleElement = element.element("role");
			if (roleElement != null) {
				host = Role.fromXML(roleElement.asXML());
			}
			/** 房间中的角色 */
			Set<Role> roles = new HashSet<Role>();
			Element rolesElement = element.element("roles");
			if (rolesElement != null) {
				Iterator<Element> iterator = rolesElement
						.elementIterator("role");
				while (iterator.hasNext()) {
					Role role = Role.fromXML(iterator.next().asXML());
					roles.add(role);
				}
			}

			room.setName(name);
			room.setStatus(XMLUtils.getRoomStatusFromStr(status));
			room.setHost(host);
			room.setRoles(roles);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return room;
	}

	/**
	 * 将当前对象转化为xml字符串
	 * 
	 * @return
	 */
	@Transient
	public String toXML() {
		StringBuffer buffer = new StringBuffer();
		buffer.append("<room>");
		buffer.append(super.toXML());
		buffer.append(XMLUtils.createSingleNode("name", this.name));
		buffer.append(XMLUtils.createSingleNode("status", this.status));
		if (this.host != null) {
			buffer.append(host.toXML());
		}
		if (!this.roles.isEmpty()) {
			buffer.append("<roles>");
			for (Role role : this.roles) {
				buffer.append(role.toXML());
			}
			buffer.append("</roles>");
		}
		buffer.append("</room>");
		return buffer.toString();
	}
}
